package y2016.date0901.pm.二维数组闭环替换;

import org.junit.jupiter.api.Test;

import java.util.Arrays;

/**
 * 合适的解决的方案，存在的问题：
 * <p>提问者sozdream回复：
 * <p>谢谢你的实现; 使用递归会遇到问题, 就是处理我这边300*300数组的时候, 会StackOverflowError, 我改成了LinkedList循环, 解决了.
 * <p>问题来自
 * <p>http://bbs.csdn.net/topics/391948572?page=1#post-401127140
 * <p>提问者：http://my.csdn.net/sozdream
 * <p>作者：http://my.csdn.net/tangxheng
 */
public class Tangxheng {
    private static final int nums[][] = {
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
            {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0},
            {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0},
            {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
            {0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0},
            {0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};

    @Test
    public void main() throws Exception {
        // 投放感染源
        toufang();

        // 打印结果
        print();
    }

    /**
     * 投放感染源，将会围绕二维数据边缘投放一圈
     */
    private static void toufang() {
        // 最上面一排投放感染源，向下方感染
        for (int i = 0; i < nums[0].length; i++) {
            ganran(0, i);
        }

        // 最左边一列投放感染源，向右方感染
        for (int i = 0; i < nums.length; i++) {
            ganran(i, 0);
        }

        // 最下面一排投放感染源，向上方感染
        for (int i = 0; i < nums[0].length; i++) {
            ganran(nums.length - 1, i);
        }

        // 最右边一列投放感染源，向左方感染
        for (int i = 0; i < nums.length; i++) {
            ganran(i, nums[i].length - 1);
        }
    }

    /**
     * 感染函数, 即投放感染源坐标，被感染值改为9
     *
     * @param x 感染源横坐标
     * @param y 感染源纵坐标
     */
    private static void ganran(int x, int y) {
        //超过数组边缘，不再感染
        if (x < 0 || y < 0 || x > nums.length - 1 || y > nums[x].length - 1) {
            return;
        }

        // 本源不可被感染
        if (nums[x][y] != 0) {
            return;
        }
        // 本源可被感染，被感染值改为9
        nums[x][y] = 9;

        // 向左感染
        ganran(x - 1, y);

        // 向上感染
        ganran(x, y - 1);

        // 向右感染
        ganran(x + 1, y);

        // 向下感染
        ganran(x, y + 1);
    }

    public static void print() {
        // 打印感染情况
        for (int[] num : nums) {
            System.out.println(Arrays.toString(num));
        }

        System.out.println("================被感染的人群来了（9）===============");
        // 还源感染，并将未感染人群设置为超人
        for (int i = 0; i < nums.length; i++) {
            for (int j = 0; j < nums[i].length; j++) {
                switch (nums[i][j]) {
                    case 9:
                        nums[i][j] = 0;
                        break;
                    case 0:
                        nums[i][j] = 2;
                        break;
                    default:
                        break;
                }

            }
        }

        System.out.println("================未感染的超人来了(2)===============");
        // 打印超人感染情况
        for (int[] num : nums) {
            System.out.println(Arrays.toString(num));
        }
    }
}

